#pragma once
#ifndef _MATRIX_H
#define _MATRIX_H

#include "vector.h"
#include "..\common\def.h"
struct Matrix4f; 

struct EE_EXPORT MATRIX3X3F
{
	float _M11,_M12,_M13,
		  _M21,_M22,_M23,
		  _M31,_M32,_M33; 


	static MATRIX3X3F transpose(MATRIX3X3F* pIn); 

	Vector3f operator * (Vector3f &op) const; 
	MATRIX3X3F(void); 
	MATRIX3X3F(const Matrix4f* pOrrientation); 
}; 

struct EE_EXPORT Matrix4f
{
	float _M11,_M12,_M13,_M14,
		  _M21,_M22,_M23,_M24,
		  _M31,_M32,_M33,_M34,
		  _M41,_M42,_M43,_M44; 

	Matrix4f(void); 
	Matrix4f
		(
			float _11, float _12, float _13, float _14, float _21, float _22, float _23, float _24, float _31, float _32,
				float _33, float _34, float _41, float _42, float _43, float _44
		); 
	Matrix4f(float M[9], float T[3]); 
	Matrix4f(float M[16]); 
	Matrix4f(float M[4][4]); 

	inline Vector3f Foward() { return Vector3f(-_M13,_M23,_M33);  }
	inline Vector3f Back() { return Vector3f(_M13,-_M23,-_M33);  }

	inline Vector3f Up() { return Vector3f(_M12,_M22,_M32);  }
	inline Vector3f Down() { return Vector3f(-_M12,-_M22,-_M32);  }

	inline Vector3f Right() { return Vector3f(_M11,-_M21,-_M31);  }
	inline Vector3f Left() { return Vector3f(-_M11,_M21,_M31);  }

	inline void SetRight(const Vector3f& vector)
	{
		_M11 = vector.x; 
		_M21 = vector.y; 
		_M31 = vector.z; 
	}

	inline void SetUp(const Vector3f& vector)
	{
		_M12 = vector.x; 
		_M22 = vector.y; 
		_M32 = vector.z; 
	}
	inline void SetForward(const Vector3f& vector)
	{
		_M13 = vector.x; 
		_M23 = vector.y; 
		_M33 = vector.z; 
	}
	inline void SetTranslation(const Vector3f& vector)
	{
		_M41 = vector.x; 
		_M42 = vector.y; 
		_M43 = vector.z; 
	}

	inline Vector3f Translation() { return Vector3f(_M41,_M42,_M43);  }
	inline Vector3f Translation() const { return Vector3f(_M41,_M42,_M43);  }

	static Matrix4f rotateX(const float angle); 
	static Matrix4f rotateY(const float angle); 
	static Matrix4f rotateZ(const float angle); 
	static Matrix4f translate(const Vector3f& vec); 
	static Matrix4f scale(const float scale); 
	static void invert(const Matrix4f* pIn,Matrix4f* pOut); 
	static Matrix4f identity(); 

	
	static Matrix4f ProjectionMatrix(const float near_plane, const float far_plane,  
		const float fov_horiz, const float aspect); 


	Vector3f operator * (Vector3f &op); 
	Vector3f operator * (Vector3f &op) const; 
	Matrix4f operator * (Matrix4f &op); 
	
	Matrix4f operator = (const Matrix4f &op); 
}; 

#endif